import dayjs from 'dayjs';
import { addLayout, LoggingEvent } from 'log4js';
import { inspect } from 'node:util';

/** 日志级别 */
export enum LoggerLevel {
  ALL = 'ALL',
  MARK = 'MARK',
  TRACE = 'TRACE',
  DEBUG = 'DEBUG',
  INFO = 'INFO',
  WARN = 'WARN',
  ERROR = 'ERROR',
  FATAL = 'FATAL',
  OFF = 'OFF',
}

/** 内容跟踪类 */
export class ContextTrace {
  constructor(
    public readonly context: string,
    public readonly path?: string,
    public readonly lineNumber?: number,
    public readonly columnNumber?: number,
  ) {}
}

/**组装日志 */
const assembleLog = () => {
  addLayout('Awesome-nest', (logConfig: any) => {
    return (logEvent: LoggingEvent) => {
      let moduleName: string = '';
      let position: string = '';

      const messageList: string[] = [];

      logEvent.data.forEach((value: any) => {
        if (value instanceof ContextTrace) {
          moduleName = value.context;
          //显示触发日志的坐标（行/列）
          if (value.lineNumber && value.columnNumber) {
            position = `${value.lineNumber},${value.columnNumber}`;
          }
          return;
        }
        if (typeof value !== 'string') {
          // 用于调试并返回对象的字符串表示形式。
          // util.inspect()方法与程序无关。它返回可以随时更改以更改结果的输出，可以通过补充选项(例如showHidden，depth)。
          // 对于检查的值，它使用构造函数名称或@@ toStringTag来创建可识别的标记。
          value = inspect(value, false, 3, true);
        }
        messageList.push(value);
      });
      //日志组成部分
      const messageOutput: string = messageList.join(' ');
      const positionOutput: string = position ? `[${position}]` : '';
      const typeOutput: string = `[${logConfig.type}]${logEvent.pid.toString()} - `;
      const dateOutput: string = `${dayjs(logEvent.startTime).format('YYYY-MM-DD HH:mm:ss')}`;
      const moduleOutput: string = moduleName ? `[${moduleName}]` : '[LoggerService]';
      let levelOutput: string = `[${logEvent.level}]${messageOutput}`;
    };
  });
};
